package com.ludomancy.sos64;

import java.awt.Point;
import java.awt.Rectangle;
import java.util.Iterator;
import java.util.Vector;

import com.ludomancy.gamelib.ImageStrip;
import com.ludomancy.gamelib.MathHelper;
import com.ludomancy.gamelib.ResourceManager;
import com.ludomancy.sos64.components.Battery;
import com.ludomancy.sos64.components.Dam;
import com.ludomancy.sos64.components.BrokenTurbine;
import com.ludomancy.sos64.components.Generator;
import com.ludomancy.sos64.components.Driller;
import com.ludomancy.sos64.components.Egg;
import com.ludomancy.sos64.components.Light;
import com.ludomancy.sos64.components.Platform;
import com.ludomancy.sos64.components.Recycler;
import com.ludomancy.sos64.components.Replicator;
import com.ludomancy.sos64.components.Turbine;

public class Game
{
	public static Game game;
	public int width;
	public int height;
	public Vector components = new Vector();
	public Terrain terrain;
	
	public static final int GROUND_TYPE_FLOOR = 0;
	public static final int GROUND_TYPE_WATER = 1;
	public static final int TILE_WIDTH = 24;
	public static final int TILE_HEIGHT = 28;
	public Dam dam;
	
	public Game(int width, int height)
	{
		game = this;
		this.width = width;
		this.height = height;
		
		// generate level
		loadTerrain(false);
		add(new Turbine(new Point(7*TILE_WIDTH - 3, 245)));
		add(new BrokenTurbine(new Point(8*TILE_WIDTH - 3, 245)));
		add(new Recycler(new Point(2*TILE_WIDTH, 1*TILE_HEIGHT)));
		add(new Replicator(new Point(125, 41)));
		Generator b = new Generator(new Point(1*TILE_WIDTH, 5*TILE_HEIGHT));
		add(b);
		add(new Platform(b));
		dam = new Dam(new Point(43, 230)); 
		add(dam);
		add(new Egg(new Point(222, 33)));
		add(new Driller(new Point(9*TILE_WIDTH,1*TILE_HEIGHT)));
		add(new Light(new Point(7*TILE_WIDTH - 3, 7 * TILE_HEIGHT + 10 - 10), 0));
		add(new Light(new Point(8*TILE_WIDTH - 3, 7 * TILE_HEIGHT + 10), 1));
		add(new Light(new Point(9*TILE_WIDTH - 3, 7 * TILE_HEIGHT + 10 - 10), 2));
		add(new Battery(new Point(8*TILE_WIDTH - 7, 6 * TILE_HEIGHT + 10 )));
		
		// debug
//		Battery b2 = new Battery(new Point(100,100));
//		b2.isFull = true;
//		add(b2);
//		add(new Teen64(new Point(200,100)));
	}
	
	public void loadTerrain(boolean endGame)
	{
		if(endGame)
		{
			terrain.tiles = new ImageStrip(ResourceManager.getImage("tiles2.png"), TILE_WIDTH, TILE_HEIGHT);
			terrain.updateTerrain();			
		}
		else
		{
			terrain = new Terrain("/map.map", new ImageStrip(ResourceManager.getImage("tiles.png"), TILE_WIDTH, TILE_HEIGHT));
			terrain.updateTerrain();
		}
	}
	
	public void startMoving(Component c, Point newPos)
	{
		c.x = newPos.x;
		c.y = newPos.y;
		c.onMoving();
	}

	public void finishMoving(Component c)
	{
		// push to end
		components.remove(c);
		components.add(c);
		c.onMoved();
		// check for collisions
		Vector toUpdate = (Vector) components.clone();
		for (Iterator iterator = toUpdate.iterator(); iterator.hasNext();)
		{
			Component cur = (Component) iterator.next();
			if(cur != c && cur.area().contains(c.getHotspot()))
			{
				c.onCollided(cur);
				cur.onCollided(c);
			}
		}
	}
	
	public void add(Component c)
	{
		components.add(c);
		c.onPlacement();
	}
	
	public Vector getComponents(Class type)
	{
		Vector ret = new Vector();
		for (Iterator iterator = components.iterator(); iterator.hasNext();)
		{
			Component c = (Component) iterator.next();
			if(c.getClass() == type)
			{
				ret.add(c);
			}
		}
		return ret;
	}
	
	public void nukeTile(Point point)
	{
		terrain.chainBreak();
	}
	
	public Component isClose(Component center, int radius, Class clazz)
	{
		for (Iterator iterator = components.iterator(); iterator.hasNext();)
		{
			Component c = (Component) iterator.next();
			if(c != center && MathHelper.dist(c.x, c.y, center.x, center.y) <= radius)
			{
				if(c.getClass() == clazz)
				{
					return c;
				}
			}

		}
		return null;		
	}
	
	public Vector getComponents(Component center, int radius)
	{
		Vector ret = new Vector();
		for (Iterator iterator = components.iterator(); iterator.hasNext();)
		{
			Component c = (Component) iterator.next();
			if(c != center && MathHelper.dist(c.x, c.y, center.x, center.y) <= radius)
			{
				ret.add(c);
			}

		}
		return ret;
	}
		
	public Component getComponent(int x, int y)
	{
		Component sel = null;
		for (Iterator iterator = components.iterator(); iterator.hasNext();)
		{
			Component c = (Component) iterator.next();
			Rectangle area = new Rectangle(c.x, c.y, c.getSize().x, c.getSize().y);
			if(area.inside(x, y) && c.available())
			{
				sel = c;
			}
		}
		return sel;
	}
		
	public void update()
	{
		terrain.update();
		Vector toUpdate = (Vector) components.clone();
		for (Iterator iterator = toUpdate.iterator(); iterator.hasNext();)
		{
			Component c = (Component) iterator.next();
			c.update();
		}
	}
	
	public boolean isIn(int tx, int ty)
	{
		return tx >= 0 && tx < width && ty >= 0 && ty < height;
	}

	public void updateSituation()
	{
	}

	public Point tileFor(Point point)
	{
		return new Point(point.x/TILE_WIDTH, point.y/TILE_HEIGHT);
	}

	public void poison()
	{
		for (int y = 0; y < terrain.height; y++)
		{
			for (int x = 0; x < terrain.width; x++)
			{
				if(terrain.isWater(x, y))
				{
					terrain.map[x][y] = Terrain.TILE_POISON;
				}
			}
		}
	}

}
